﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using CodeCreator.CoreObj;
using CodeCreator.Template;
using Microsoft.VisualBasic.FileIO;
using CodeCreator.DbHelper;

namespace CodeCreator
{
    public partial class FrmMain : Form
    {
        string dbConfigFilePath = System.Windows.Forms.Application.StartupPath + "/Config/dbinfo.xml";
        List<TypeMap> typeMapList = new List<TypeMap>();
        List<Obj> objList = new List<Obj>();
        IDbHelper dbHelper = null;

        public FrmMain()
        {
            InitializeComponent();
            this.dataGridView1.AutoGenerateColumns = false;
            JavaMap t = new JavaMap();
        }

        public void addObjListForSql()
        {
            objList= new List<Obj>();
            Obj obj = new Obj();
            obj.ClassName = this.txtClassName.Text.Trim();
            obj.PackageName = this.txtPackageName.Text.Trim();
            obj.TableFullName = ".";
            DbInfo dbInfo = cmbDbInfo.SelectedItem as DbInfo;
            if (dbInfo != null)
            {
                DbHelper.IDbHelper dbHelper= null;
                switch (dbInfo.Type.ToUpper())
                {
                    case "MYSQL":
                        dbHelper = new DbHelperForMySql(dbInfo.ConnectionString);
                        break;
                    case "ORACLE":
                        dbHelper = new DbHelperForOracle(dbInfo.ConnectionString);
                        break;
                }
                string strSql = this.richTextBox1.Text.Trim();
                string strCheckSql = "select * from (" + strSql + ") a where 1=2";
                DataSet ds = dbHelper.Query(strCheckSql);
                if (ds != null && ds.Tables.Count > 0)
                {
                    List<ObjField> ofList = new List<ObjField>();
                    foreach (DataColumn dc in ds.Tables[0].Columns)
                    {
                        ObjField of = new ObjField();
                        of.DbFieldLength = "1024";
                        of.DbFieldName = dc.ColumnName;
                        of.DbFieldPk = false;
                        of.DbSequence = null; ;
                        TypeMap tm = Common.GetTypeMapByCSharp(this.typeMapList, dc.DataType.Name);
                        if (tm != null)
                        {
                            of.DbFieldType = tm.DbType;
                            of.ClassFieldType = tm.ClassType;
                            of.JsFieldType = tm.JsType;
                        }
                        else
                        {
                            of.DbFieldType = dc.DataType.Name;
                            of.ClassFieldType = dc.DataType.Name;
                            of.JsFieldType = dc.DataType.Name;
                        }
                        ofList.Add(of);
                    }
                    obj.Fields = ofList;
                }

                string strNewSql = "select ";
                foreach (ObjField of in obj.Fields)
                {
                    strNewSql += "\r\n\t\t" + of.DbFieldName + " as " + of.ClassFieldNameFirstLower + ",";
                }
                if (strNewSql.EndsWith(","))
                    strNewSql = strNewSql.Substring(0, strNewSql.Length - 1);
                strNewSql += "\r\n\tfrom (";
                strNewSql += "\r\n\t" + strSql;
                strNewSql += "\r\n\t)";
                ObjSql os = new ObjSql("select", strNewSql);
                List<ObjSql> osList = new List<ObjSql>();
                osList.Add(os);
                obj.Sqls = osList;
            }

            this.objList.Add(obj);
        }

        string templateFilePath = "";
        string codeFilePath = "";
        private void btnCreateCode_Click(object sender, EventArgs e)
        {
            //判断目录
            if (!Directory.Exists(this.txtCodePath.Text))
            {
                using (FrmMessage fr = new FrmMessage("主人，代码生成目录不存在，请选择！"))
                {
                    fr.ShowDialog(this);
                    this.txtCodePath.Focus();
                }
                return;
            }
            //判断命名空间
            if (this.txtPackageName.Text == "com.inspur.plugins.")
            {
                using (FrmMessage fr = new FrmMessage("主人，请填写包名！"))
                {
                    fr.ShowDialog(this);
                    this.txtPackageName.Focus();
                }
                return;
            }

            List<string> fileList = new List<string>();
            //拷贝模板到指定目录下后循环遍历文件
            TemplateInfo template = this.cmbTemplates.SelectedItem as TemplateInfo;
            if (template != null)
            {
                fileList.Clear();
                templateFilePath = template.Path;
                codeFilePath = this.txtCodePath.Text.Trim();

                if (this.chkAddCode.Checked)
                {
                    if (codeFilePath.EndsWith("\\"))
                        codeFilePath += "code";
                    else
                        codeFilePath += "\\code";
                }

                if (!Directory.Exists(codeFilePath))
                {
                    Directory.CreateDirectory(codeFilePath);
                }

                List<string> exceptDir = new List<string>();
                exceptDir.Add(".svn");
                List<string> exceptFile = new List<string>();
                exceptFile.Add("TypeMap.xml");

                fileList = ToolsFile.CopyDirectory(templateFilePath, codeFilePath, template.Path,exceptDir,exceptFile);
            }

            try
            {
                //判断是否用SQL生成
                if (this.tabControl1.SelectedTab == this.tabPage2)
                {
                    //判断命名空间
                    if (this.txtClassName.Text.Trim() == "")
                    {
                        using (FrmMessage fr = new FrmMessage("主人，请填写类名！"))
                        {
                            fr.ShowDialog(this);
                            this.txtClassName.Focus();
                        }
                        return;
                    }
                    this.addObjListForSql();
                }

                //处理数据库对象，生成Obj
                foreach (Obj obj in objList)
                {
                    obj.PackageName = this.txtPackageName.Text.Trim();
                    foreach (string file in fileList)
                    {
                        FileToReplace.replaceFile(file, obj);
                    }
                }

                //删除模板文件
                foreach (string file in fileList)
                {
                    if (File.Exists(file))
                        File.Delete(file);
                }

                using (FrmMessage fr = new FrmMessage("查看","关闭","主人，生成完了，是否检查一下？"))
                {
                    if (fr.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
                    {
                        System.Diagnostics.Process.Start("Explorer.exe", codeFilePath);
                    }
                }
            }
            catch(Exception ex)
            {
                using (FrmMessage fr = new FrmMessage("查看", "关闭", "出错了，错误："+ex.Message))
                {
                    fr.ShowDialog(this);
                }
            }
        }      

        private void btnSetDbInfo_Click(object sender, EventArgs e)
        {
            using (FrmDbManager dbManager = new FrmDbManager())
            {
                dbManager.StartPosition = FormStartPosition.CenterParent;
                if (dbManager.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
                {
                    List<DbInfo> dbInfoList = ToolsSerialize.XmlDeserialize<List<DbInfo>>(dbConfigFilePath);
                    this.cmbDbInfo.DataSource = dbInfoList;
                }
            }
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            List<DbInfo> dbInfoList = ToolsSerialize.XmlDeserialize<List<DbInfo>>(dbConfigFilePath);
            this.cmbDbInfo.DataSource = dbInfoList;
            RefreshTemplates();
        }

        private void RefreshTemplates()
        {
            string strDir = Application.StartupPath + "/Templates";
            if (Directory.Exists(strDir))
            {
                string[] dirs = Directory.GetDirectories(strDir);
                List<TemplateInfo> templates = new List<TemplateInfo>();
                foreach (string str in dirs)
                {
                    if (!str.EndsWith(".svn"))
                    {
                        DirectoryInfo di = new DirectoryInfo(str);
                        templates.Add(new TemplateInfo(di.Name, di.FullName));
                    }
                }
                this.cmbTemplates.DataSource = templates;
                this.cmbTemplates.DisplayMember = "Name";
            }
        }

        private void btnRefreshTemplates_Click(object sender, EventArgs e)
        {
            RefreshTemplates();
        }

        private void cmbTemplates_SelectedIndexChanged(object sender, EventArgs e)
        {
            TemplateInfo template = this.cmbTemplates.SelectedItem as TemplateInfo;
            if (template != null)
            {
                if (File.Exists(template.Path + "\\TypeMap.xml"))
                {
                    this.typeMapList = ToolsSerialize.XmlDeserialize<List<TypeMap>>(template.Path + "\\TypeMap.xml");
                }
                else
                {
                    this.typeMapList.Clear();
                }
            }
        }

        private void cmbDbInfo_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.objList = new List<Obj>();
            this.dataGridView1.DataSource = this.objList;
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.objList = new List<Obj>();
            this.dataGridView1.DataSource = this.objList;
        }

        private void btnCheckTables_Click(object sender, EventArgs e)
        {
            DbInfo dbInfo = cmbDbInfo.SelectedItem as DbInfo;
            //objList.Clear();
            if (dbInfo != null)
            {
                //生成DbHelper
                switch (dbInfo.Type.ToUpper())
                {
                    case "MYSQL":
                        dbHelper = new DbHelperForMySql(dbInfo.ConnectionString);
                        break;
                    case "ORACLE":
                        dbHelper = new DbHelperForOracle(dbInfo.ConnectionString);
                        break;
                }
                DbManager.FrmCheckTables frm = new DbManager.FrmCheckTables(dbHelper);
                frm.StartPosition = FormStartPosition.CenterParent;
                frm.typeMapList = this.typeMapList;
                if (frm.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
                {
                    objList = frm.objList;                   
                    this.dataGridView1.AutoGenerateColumns = false;
                    this.dataGridView1.DataSource = objList;
                }
            }
        }

        private void btnGetDir_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog frm = new FolderBrowserDialog();
            if (frm.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
            {
                this.txtCodePath.Text = frm.SelectedPath;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string strPath = this.txtCodePath.Text.Trim();
            if (this.chkAddCode.Checked)
            {
                if (strPath.EndsWith("\\"))
                    strPath += "code\\";
                else
                    strPath += "\\code\\";
            }
            else
            {
                if (!strPath.EndsWith("\\"))
                    strPath += "\\";
            }

            using (FrmMessage fr = new FrmMessage("确定", "取消", "主人，您正在进行极其危险的操作，确定要删除\n"+strPath+"\n目录下所有文件吗？"))
            {
                if (fr.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
                {
                    if (Directory.Exists(strPath))
                    {
                        foreach (string f in Directory.GetFiles(strPath))
                        {
                            FileSystem.DeleteFile(f, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);

                        }

                        foreach (string d in Directory.GetDirectories(strPath))
                        {
                            FileSystem.DeleteDirectory(d, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
                        }
                    }
                    FrmMessage frOk = new FrmMessage("主人，清理成功,文件已经丢到回收站！");
                    frOk.ShowDialog(this);
                }
            }            
        }

        private void button2_Click(object sender, EventArgs e)
        {
            TemplateInfo template = this.cmbTemplates.SelectedItem as TemplateInfo;
            if (template != null)
            {
                if (Directory.Exists(template.Path))
                {
                    System.Diagnostics.Process.Start("Explorer.exe", template.Path);
                }
                else
                {
                    FrmMessage frOk = new FrmMessage("主人，没有模板路径！\n" + template.Path);
                    frOk.ShowDialog(this);
                }
            }
        }
    }
}
